/*
 *  Copyright (C) 1993  Robert Davis
 *
 *  This program is free software; you can redistribute it and/or
 *  modify it under the terms of Version 2, or any later version, of 
 *  the GNU General Public License as published by the Free Software 
 *  Foundation.
 */


static char RCSId[]="$Id: GeneralPane.m,v 1.9 1993/05/18 03:55:06 davis Exp $";


#import <appkit/Application.h>
#import <appkit/Box.h>
#import <appkit/Button.h>
#import <appkit/Matrix.h>
#import <appkit/Panel.h>		/* NXRunAlertPanel()		*/
#import <appkit/Slider.h>
#import <appkit/Text.h>			/* GeneralPane is a text delegate */
#import <appkit/TextField.h>
#import <appkit/TextFieldCell.h>
#import <appkit/View.h>

#import <objc/NXStringTable.h>

#import "GeneralPane.h"
#import "Status.h"


@interface GeneralPane (Private)

- _updateKeyIsThreeD:(BOOL)isThreeD;
- _updateSize;
- _updateTime;

@end


@implementation GeneralPane


- init
{
    [super init];

    [NXApp loadNibSection: "GeneralPane.nib"
		    owner: self
		withNames: NO
		 fromZone: [self zone]];

    icon = "InspectorGeneral.tiff";
    return self;
}


/*  
 *  The following methods should be overridden by subclasses.
 */
- selectControl:sender
{
    [titleField selectText:self];
    return self;
}


- (BOOL)updateStatus:aStatus doc:aDoc
{
    id oldStatus = status;

    /*  
     *  We only bother updating if status has changed since we last 
     *  updated, or if we just became the current pane (didSwap) -- 
     *  assuming that status and aDoc are non-nil, of course.
     */

    if ([super updateStatus:aStatus doc:aDoc]
	&& ((status != oldStatus) || didSwap)) {

	BOOL isThreeD = [status isThreeD];
	BOOL isPolar = [status isPolar];
	Window *viewWindow;
	id anId;

	[(viewWindow = [view window]) disableDisplay];

        [polarButton setState:isPolar];
        [polarButton setEnabled:!isThreeD];
        [parametricButton setState:[status parametric]];
        [borderButton setState:[status border]];
        [self _updateKeyIsThreeD:isThreeD];
        [self _updateTime];
        [[samplesMatrix findCellWithTag:X_TAG] setIntValue:
						[status samples:X_TAG]];
	anId = [samplesMatrix findCellWithTag:Y_TAG];
        [anId setIntValue:[status samples:Y_TAG]];
	[anId setEnabled:isThreeD];

        [self _updateSize];
        [titleField setStringValue:[status title]];

	[viewWindow reenableDisplay];

	[self perform:@selector(selectControl:)
		 with:self
	   afterDelay:1
       cancelPrevious:YES];

	didSwap = NO;
	return YES;
    }

    return NO;
}


- didSwapIn:sender
{
    didSwap = YES;
    return self;
}



- doSetPlotTitle:sender
{
    [status setTitle: [sender stringValue]];
    [sender setStringValue:[status title]];   /* status may have fixed title */

    return self;
}


- doSetSizeProp:sender
{
    float aValue;

    if ([sender state])  {

        [status setSizeProp: 1];

        [status setSizeX:0
	      Y: aValue = [[sizeTextMatrix findCellWithTag:X_TAG] floatValue]];
        [sizeYSlider setFloatValue:aValue];
        [[sizeTextMatrix findCellWithTag:Y_TAG] setFloatValue:aValue];

    } else
        [status setSizeProp: 0];

    return self;
}


- doSetSize:sender
{
    float val[((X_TAG > Y_TAG)? X_TAG : Y_TAG) + 1];
    int tag;
    Cell *cell = [sender selectedCell];

    val[tag = [sender selectedTag]] = [cell floatValue];
    if ([sizeButton state])
	val[(X_TAG == tag)? Y_TAG : X_TAG] = val[tag];
    else
	val[(X_TAG == tag)? Y_TAG : X_TAG] = 0.0;

    [status setSizeX:val[X_TAG] Y:val[Y_TAG]];
    [self _updateSize];

    return self;
}


- doSetBorder:sender
{
    return [status setBorder:[sender state]];
}


- doSetPolar:sender
{
    [status setPolar:[sender state]];
    if ([self forceUpdateStatus:status doc:doc])
	[view display];
    return self;
}




/*  
 *  This method informs the user the first time it is sent that 
 *  parametric plots have special requirements.
 */
- doSetParametric:sender
{
    static BOOL didInform = NO;
    int state = [sender state];

    if (!didInform && state) {
        didInform = YES;
        NXRunAlertPanel ([stringSet valueForStringKey: "parametric"],
                         [stringSet valueForStringKey: "needEvenFunctions"],
                         NULL, NULL, NULL);
    }   
    
    return [status setParametric:state];
}


- doSetSamples:sender
{
    int samples = [sender intValue];
    if (samples > 1)
	[status setSamplesCoord:[sender selectedTag] to:samples];
    else
	[sender setIntValue:[status samples:[sender selectedTag]]];

    return self;
}


- doSetKey:sender
{
    [status setKey: [sender state]];
    [self _updateKeyIsThreeD:[status isThreeD]];
    if (![keyDefaultButton state])
	[keyMatrix selectCellWithTag:X_TAG];

    return self;
}


- doSetKeyLocation:sender
{
    id cell = [sender selectedCell];
    int tag = [cell tag];
    double val = [cell doubleValue];

    if ([status isLogCoord:tag] && (val <= 0))  {
        NXRunAlertPanel ([stringSet valueForStringKey: "key"],
                         [stringSet valueForStringKey: "logKey"],
                         NULL, NULL, NULL);
        [self _updateKeyIsThreeD:[status isThreeD]];
    } else
        [status setKeyCoord:tag to:val];

    return self;
}


- doSetKeyDefault:sender
{
    int i;
    BOOL ok = YES;
    BOOL isDefaultOn = [sender state];

    for (i = 0 ; i < 3 ; i++)
        if ([status isLogCoord:i] && ([[keyMatrix findCellWithTag:i]
                                                doubleValue] <= 0)) {
            NXRunAlertPanel ([stringSet valueForStringKey: "key"],
                             [stringSet valueForStringKey: "logKey"],
                             NULL, NULL, NULL);
            ok = NO;
            break;
        }

    if (ok)
        [status setKeyDefault: isDefaultOn];

    [self _updateKeyIsThreeD:[status isThreeD]];

    if (ok && !isDefaultOn)
	[keyMatrix selectCellWithTag:X_TAG];

    return self;
}


- doSetTime:sender
{
    [status setTime: [sender state]];
    [self _updateTime];

    if (![timeDefaultButton state])
	[timeMatrix selectCellWithTag:X_TAG];

    return self;
}


- doSetTimeLocation:sender
{
    id cell = [sender selectedCell];
    int tag = [cell tag];
    int val = [cell intValue];

    if ([status isLogCoord:tag] && (val <= 0))  {
        NXRunAlertPanel ([stringSet valueForStringKey: "time"],
                         [stringSet valueForStringKey: "logTime"],
                         NULL, NULL, NULL);
        [self _updateTime];
    } else
        [status setTimeCoord:tag to:val];

    return self;
}


- doSetTimeDefault:sender
{
    int i;
    BOOL ok = YES;
    BOOL isDefaultOn = [sender state];

    for (i = 0 ; i < 2 ; i++)
        if ([status isLogCoord:i] && ([[timeMatrix findCellWithTag:i]
                                                doubleValue] <= 0)) {
            NXRunAlertPanel ([stringSet valueForStringKey: "time"],
                             [stringSet valueForStringKey: "logTime"],
                             NULL, NULL, NULL);
            ok = NO;
            break;
        }

    if (ok)
        [status setTimeDefault: isDefaultOn];

    [self _updateTime];

    if (ok && !isDefaultOn)
	[timeMatrix selectCellWithTag:X_TAG];

    return self;
}



// Shuts up the compiler about unused RCSId
- (const char *) rcsid
{
    return RCSId;
}


@end


@implementation GeneralPane (Private)


- _updateKeyIsThreeD:(BOOL)isThreeD
{
    int keyState = [status key];
    int keyDefaultState = [status keyDefault];
    int i;

    for (i = 0 ; i <= 2 ; i++)
        [[keyMatrix findCellWithTag:i] setDoubleValue:[status keyCoord:i]];

    [keyButton setState: keyState];
    [keyDefaultButton setState: keyDefaultState];
    [keyDefaultButton setEnabled: keyState];

    if (keyState) {                     /* There is a key...            */

        [[keyMatrix findCellWithTag:X_TAG] setEnabled:!keyDefaultState];
	[[keyLabelMatrix findCellWithTag:X_TAG] 
			     setTextGray:keyDefaultState? NX_DKGRAY: NX_BLACK];

        [[keyMatrix findCellWithTag:Y_TAG] setEnabled:!keyDefaultState];
	[[keyLabelMatrix findCellWithTag:Y_TAG] 
			     setTextGray:keyDefaultState? NX_DKGRAY: NX_BLACK];

        [[keyMatrix findCellWithTag:Z_TAG] setEnabled:!keyDefaultState
                                                      && isThreeD];
	[[keyLabelMatrix findCellWithTag:Z_TAG] 
	      setTextGray:(keyDefaultState || !isThreeD)? NX_DKGRAY: NX_BLACK];


    } else                            /* There is no key              */
        for (i = 0 ; i < 3 ; i++)  {
            [[keyMatrix findCellWithTag:i] setEnabled:NO];
	    [[keyLabelMatrix findCellWithTag:i] setTextGray:NX_DKGRAY];
	}

    return self;
}



- _updateSize
{
    float value;

    [sizeXSlider setFloatValue:value = [status sizeX]];
    [[sizeTextMatrix findCellWithTag:X_TAG] setFloatValue:value];
    if ([status sizeProp])  {
        [sizeYSlider setFloatValue:value = [status sizeY]];
        [[sizeTextMatrix findCellWithTag:Y_TAG] setFloatValue:value];
        [sizeButton setState:1];
    } else {
        [sizeYSlider setFloatValue:value = [status sizeY]];
        [[sizeTextMatrix findCellWithTag:Y_TAG] setFloatValue:value];
        [sizeButton setState:0];
    }

    return self;
}




- _updateTime
{
    int timeState = [status time];
    int timeDefaultState = [status timeDefault];

    [[timeMatrix findCellWithTag:X_TAG] setIntValue: [status timeCoord:X_TAG]];
    [[timeMatrix findCellWithTag:Y_TAG] setIntValue: [status timeCoord:Y_TAG]];

    [timeButton setState: timeState];
    [timeDefaultButton setState: timeDefaultState];
    [timeDefaultButton setEnabled: timeState];

    if (timeState) {                    /* We do want to show time/date */

        [[timeMatrix findCellWithTag:X_TAG] setEnabled:!timeDefaultState];
	[[timeLabelMatrix findCellWithTag:X_TAG]
			setTextGray: timeDefaultState? NX_DKGRAY: NX_BLACK];
        [[timeMatrix findCellWithTag:Y_TAG] setEnabled:!timeDefaultState];
	[[timeLabelMatrix findCellWithTag:Y_TAG]
			setTextGray: timeDefaultState? NX_DKGRAY: NX_BLACK];

    } else {                            /* We don't want to show time   */

        [[timeMatrix findCellWithTag:X_TAG] setEnabled:NO];
	[[timeLabelMatrix findCellWithTag:X_TAG] setTextGray: NX_DKGRAY];
        [[timeMatrix findCellWithTag:Y_TAG] setEnabled:NO];
	[[timeLabelMatrix findCellWithTag:Y_TAG] setTextGray: NX_DKGRAY];

    }
    return self;
}




@end
